﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace Utility.Web
{
    public class WebUpload
    {
        /// <summary>
        ///     Upload file with some format
        /// </summary>
        /// <param name="objectFile"></param>
        /// <param name="pathDirectory">relative path ex: ~/Upload/Avatar/</param>
        /// <param name="errorMess">out put message, ex: succsess or error</param>
        /// <param name="fileName">out put filename when done , ex :2010110634054.jpg</param>
        /// <param name="formatFileName">list of format ex :jpg,jpeg,gif; unless put "" to acccept all type</param>
        /// <returns></returns>
        public static bool UploadFile(HttpPostedFileBase objectFile, string pathDirectory, ref string errorMess, ref string fileName, string formatFileName, int maxSize)
        {
            if (objectFile.FileName != "")
            {
                HttpPostedFileBase postfile = objectFile;
                //Lấy tên phần mở rộng của File được Upload
                string fileExtension = Path.GetExtension(postfile.FileName).ToLower();
                fileExtension = fileExtension.Substring(1, fileExtension.Length - 1);//.jpg->jpg
                /*----------Kiem tra pham mo rong file-----*/
                if (formatFileName != "")
                {
                    if (CheckExtention(formatFileName, fileExtension) == false)//Not exits
                    {
                        errorMess = "Chỉ được chọn file  theo yêu cầu : " + formatFileName;
                        return false;
                    }
                }
                int fileSize = postfile.ContentLength;
                if (fileSize == 0)
                {
                    errorMess = "File không có dung lượng !";
                    return false;
                }

                if (fileSize > maxSize)
                {
                    errorMess = "Chỉ upload những file có dung lượng <= " + (maxSize / 1000).ToString() + "KB";
                    return false;
                }

                fileName = (fileName == string.Empty) ? RandomManage.RandomFileName() + "." + fileExtension : fileName + RandomManage.RandomFileName() + "." + fileExtension;
                //Ghi file mới
                try
                {
                    byte[] dataFile = new byte[fileSize];
                    postfile.InputStream.Read(dataFile, 0, fileSize);

                    FileStream newFile = new FileStream(HttpContext.Current.Server.MapPath(pathDirectory + fileName), FileMode.Create);
                    newFile.Write(dataFile, 0, fileSize);
                    newFile.Close();
                    errorMess = "Upload thành công!";
                    return true;
                }
                catch //(Exception e)
                {
                    try
                    {
                        WebUlti.DeleteFile(pathDirectory + fileName);
                        errorMess = "Lỗi trong khi Upload!";// +e.Message;
                        return false;
                    }
                    catch //(Exception ex)
                    {
                        errorMess = "Đường dẫn không đúng ! ";// +ex.Message;
                        return false;
                    }
                }
            }
            else
            {
                errorMess = "Hãy chọn file để upload!";
                return false;
            }
        }

        /// <summary>
        /// Check file extention 
        /// </summary>
        /// <param name="formatFileName">ex : "jpg,jpeg,gif,png"</param>
        /// <param name="ext">ext need to check in listFormat, ex : jpg</param>
        /// <returns></returns>
        public static bool CheckExtention(string formatFileName, string ext)
        {
            List<string> listFormat = ListSpilit(formatFileName, ',');
            foreach (string e in listFormat)
                if (e.ToLower() == ext.ToLower())
                    return true;
            return false;
        }

        public static List<string> ListSpilit(string listFormat, char sperator)
        {
            char[] sperators = new char[] { sperator };
            string str = listFormat;
            string[] lst = str.Split(sperator);
            List<string> l = new List<string>();
            l.AddRange(lst);
            return l;
        }

        public enum SaveOriginal
        {
            Yes,
            No
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="imageSavePath">path to save the newImage after resized</param>
        /// <param name="fileName">the file name for new image is resized</param>
        /// <param name="maxWidth">the width for new image you want to resize</param>
        /// <param name="maxHeight">the height for new image you want to resize</param>
        /// <param name="saveOriginalImage">Yes if you want to save original image file</param>
        /// <param name="maxWidthOri">if 'SaveOriginal.Yes' : How many pixels you want to set the width for original image file?</param>
        /// <param name="maxHeightOri">if 'SaveOriginal.Yes' : How many pixels you want to set the height for original image file?</param>
        /// <param name="originalFileName">if 'SaveOriginal.Yes' : What do you want to set the file name?</param>
        /// <param name="origianlSavePath">if 'SaveOriginal.Yes' : What do you want to set the file path to save it?</param>
        /// <param name="buffer">The image from control</param>
        /// <returns></returns>
        public static bool ResizeFromStream(string imageSavePath, ref string fileName, int maxWidth,/*--new code*/int maxHeight, SaveOriginal saveOriginalImage, int maxWidthOri,/*--new code*/int maxHeightOri, ref string originalFileName, string origianlSavePath, HttpPostedFileBase buffer)
        {
            try
            {
                int intNewWidth;
                int intNewHeight;
                Image imgInput = Image.FromStream(buffer.InputStream);

                //get image original width and height
                int intOldWidth = imgInput.Width;
                int intOldHeight = imgInput.Height;

                #region new code to define new size
                /*----new code--*/

                intNewWidth = intOldWidth;
                intNewHeight = intOldHeight;

                double aspectRatio = (double)intOldWidth / (double)intOldHeight;

                if (aspectRatio <= 1 && intOldWidth > maxWidth)
                {
                    intNewWidth = maxWidth;
                    intNewHeight = (int)Math.Round(intNewWidth / aspectRatio);
                }
                else if (aspectRatio > 1 && intOldHeight > maxHeight)
                {
                    intNewHeight = maxHeight;
                    intNewWidth = (int)Math.Round(intNewHeight * aspectRatio);
                }
                /*---end new code---*/
                #endregion

                //create new bitmap
                Bitmap bmpResized = new Bitmap(imgInput, intNewWidth, intNewHeight);

                /*--HighQuality: if neccessary uncomment this code--*/

                Graphics gr = Graphics.FromImage(bmpResized);
                gr.SmoothingMode = SmoothingMode.HighQuality;
                gr.CompositingQuality = CompositingQuality.HighQuality;
                gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                gr.InterpolationMode = InterpolationMode.HighQualityBicubic;

                Rectangle rectDestination = new Rectangle(0, 0, intNewWidth, intNewHeight);
                gr.DrawImage(imgInput, rectDestination, 0, 0, intOldWidth, intOldHeight, GraphicsUnit.Pixel);

                /*---End HighQuality--*/

                //save bitmap to disk
                string fileExtension = ".jpg";//Path.GetExtension(buffer.FileName).ToLower();
                fileName = (fileName == string.Empty) ? RandomManage.RandomFileName() + fileExtension : fileName + RandomManage.RandomFileName() + fileExtension;
                bmpResized.Save(HttpContext.Current.Server.MapPath(imageSavePath + fileName), ImageFormat.Jpeg/*imgInput.RawFormat*/);

                //save original image
                if (saveOriginalImage == SaveOriginal.Yes)
                {
                    //more
                    intNewWidth = intOldWidth;
                    intNewHeight = intOldHeight;

                    if (aspectRatio <= 1 && intOldWidth > maxWidthOri)
                    {
                        intNewWidth = maxWidthOri;
                        intNewHeight = (int)Math.Round(intNewWidth / aspectRatio);
                    }
                    else if (aspectRatio > 1 && intOldHeight > maxHeightOri)
                    {
                        intNewHeight = maxHeightOri;
                        intNewWidth = (int)Math.Round(intNewHeight * aspectRatio);
                    }

                    bmpResized = new Bitmap(imgInput, intNewWidth, intNewHeight);

                    gr = Graphics.FromImage(bmpResized);
                    gr.SmoothingMode = SmoothingMode.HighQuality;
                    gr.CompositingQuality = CompositingQuality.HighQuality;
                    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;

                    rectDestination = new Rectangle(0, 0, intNewWidth, intNewHeight);
                    gr.DrawImage(imgInput, rectDestination, 0, 0, intOldWidth, intOldHeight, GraphicsUnit.Pixel);
                    //end more

                    originalFileName = (originalFileName == string.Empty) ? RandomManage.RandomFileName() + fileExtension : originalFileName + RandomManage.RandomFileName() + fileExtension;
                    //bmpResized = new Bitmap(imgInput, intOldWidth, intOldHeight);
                    bmpResized.Save(HttpContext.Current.Server.MapPath(origianlSavePath + originalFileName), ImageFormat.Jpeg/*imgInput.RawFormat*/);
                }

                //release used resources
                imgInput.Dispose();
                bmpResized.Dispose();
                buffer.InputStream.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="imageSavePath">path to save the newImage after resized</param>
        /// <param name="fileName">the file name for new image is resized</param>
        /// <param name="maxWidth">the width for new image you want to resize</param>
        /// <param name="maxHeight">the height for new image you want to resize</param>        
        /// <param name="buffer">The image from control</param>
        /// <returns></returns>
        public static bool SaveFileAfterResize(string imageSavePath, ref string fileName, int maxWidth,/*--new code*/int maxHeight, HttpPostedFileBase buffer, int maxSize, ref string errorMess)
        {
            try
            {
                int fileSize = buffer.ContentLength / 1024;
                if (fileSize == 0)
                {
                    errorMess = "File size is empty!";
                    return false;
                }

                if (fileSize > maxSize)
                {
                    errorMess = "This file exceeds the " + (maxSize / 1024).ToString() + "MB attachment limit. Sorry.";
                    return false;
                }

                int intNewWidth;
                int intNewHeight;
                Image imgInput = Image.FromStream(buffer.InputStream);

                //get image original width and height
                int intOldWidth = imgInput.Width;
                int intOldHeight = imgInput.Height;

                #region new code to define new size
                /*----new code--*/

                intNewWidth = intOldWidth;
                intNewHeight = intOldHeight;

                double aspectRatio = (double)intOldWidth / (double)intOldHeight;

                if (intOldWidth > maxWidth)
                {
                    intNewWidth = maxWidth;
                    intNewHeight = (int)Math.Round(intNewWidth / aspectRatio);
                }
                else if (aspectRatio > 1 && intOldHeight > maxHeight)
                {
                    intNewHeight = maxHeight;
                    intNewWidth = (int)Math.Round(intNewHeight * aspectRatio);
                }
                /*---end new code---*/
                #endregion

                //create new bitmap
                Bitmap bmpResized = new Bitmap(imgInput, intNewWidth, intNewHeight);

                /*--HighQuality: if neccessary uncomment this code--*/

                Graphics gr = Graphics.FromImage(bmpResized);
                gr.SmoothingMode = SmoothingMode.HighQuality;
                gr.CompositingQuality = CompositingQuality.HighQuality;
                gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                gr.InterpolationMode = InterpolationMode.HighQualityBicubic;

                Rectangle rectDestination = new Rectangle(0, 0, intNewWidth, intNewHeight);
                gr.DrawImage(imgInput, rectDestination, 0, 0, intOldWidth, intOldHeight, GraphicsUnit.Pixel);

                /*---End HighQuality--*/

                //save bitmap to disk
                string fileExtension = ".jpg";//Path.GetExtension(buffer.FileName).ToLower();
                fileName = (fileName == string.Empty) ? RandomManage.RandomFileName() + fileExtension : fileName + RandomManage.RandomFileName() + fileExtension;
                bmpResized.Save(HttpContext.Current.Server.MapPath(imageSavePath + fileName), ImageFormat.Jpeg/*imgInput.RawFormat*/);
               
                //release used resources
                imgInput.Dispose();
                bmpResized.Dispose();
                buffer.InputStream.Close();
            }
            catch (Exception e)
            {
                errorMess = e.Message;
                return false;
            }
            return true;
        }
    }
}
